﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace AudiPyme.DAL
{
    public static class Matriz_Amenazas_ControlesFactory
    {
        //Inserta una nueva relación amenaza - control en la base de conocimiento
        public static void InsertarMatriz_Amenazas_Controles(Matriz_Amenazas_Controles AmenazaControl)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToMatriz_Amenazas_ControlesEstablecer(AmenazaControl);
            agenteBD.SaveChanges();
        }

        //Inserta una nueva relación amenaza - control en la base de conocimiento a través de los nombres de los elementos que la componen
        public static void Inserta_Relacion_Amenaza_Control(String AmenazaSeleccionada, String ControlSeleccionado)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Matriz_Amenazas_Controles matriz = new Matriz_Amenazas_Controles();
            //Recogemos los Id's asociados a la Amenaza y el Control seleccionado
            int IdAmenazaSelec = AmenazasFactory.BuscarIdAmenaza(AmenazaSeleccionada);
            int IdControlSelec = ControlesFactory.IdControl(ControlSeleccionado);
            IQueryable<Matriz_Amenazas_Controles> Relacion = from Matriz in agenteBD.Matriz_Amenazas_ControlesEstablecer
                                                             where Matriz.IdAmenaza == IdAmenazaSelec && Matriz.IdControl == IdControlSelec
                                                             select Matriz;
            //Si la relacion no existe en la base de datos
            if (Relacion.Count() == 0)
            {
                //se inserta
                Matriz_Amenazas_Controles nuevaRelacion = new Matriz_Amenazas_Controles();
                nuevaRelacion.IdAmenaza = IdAmenazaSelec;
                nuevaRelacion.IdControl = IdControlSelec;
                nuevaRelacion.Actual = true;
                InsertarMatriz_Amenazas_Controles(nuevaRelacion);
            }
            //Si existe se actualiza su valor Actual a true
            else
            {
                Relacion.First().Actual = true;
                agenteBD.SaveChanges();
            }
        }

        //Indica si una relación amenaza - control está almacenada en la base de conocimiento
        public static bool EstaMatriz_Amenazas_Controles(String AmenazaSeleccionada, String ControlSeleccionado)
        {
            bool esta = false;
            ModeloContainer agenteBD = new ModeloContainer();
            int IdAmenazaSelec = AmenazasFactory.BuscarIdAmenaza(AmenazaSeleccionada);
            int IdControlSelec = ControlesFactory.IdControl(ControlSeleccionado);
            IQueryable<Matriz_Amenazas_Controles> RelacionEncontrada = from MatrAmenContr in agenteBD.Matriz_Amenazas_ControlesEstablecer
                                                                       where MatrAmenContr.IdAmenaza == IdAmenazaSelec && MatrAmenContr.IdControl == IdControlSelec
                                                                       select MatrAmenContr;
            //Si está la relación y con el campo actual a true se devuelve un true
            if (RelacionEncontrada.Count() != 0 && RelacionEncontrada.First().Actual == true)
            {
                esta = true;
            }
            return esta;
        }

        //Realiza un eliminado de una relación amenaza - control
        public static void EliminarMatriz_Amenazas_Controles(Matriz_Amenazas_Controles matriz)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Matriz_Amenazas_Controles> MatrizAmenContr
                                         = from MAC in agenteBD.Matriz_Amenazas_ControlesEstablecer
                                           where MAC.IdAmenaza == matriz.IdAmenaza &&
                                                 MAC.IdControl == matriz.IdControl
                                           select MAC;
            agenteBD.Matriz_Amenazas_ControlesEstablecer.DeleteObject(MatrizAmenContr.First());
            agenteBD.SaveChanges();
        }

        //Método que recoge el número de Relaciones Tipo Activo - Amenaza de la Matriz 
        public static int NumRelacAmenContr()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int nRelac = (from RelacTipActVuln in agenteBD.Matriz_Amenazas_ControlesEstablecer
                          where RelacTipActVuln.Actual == true
                          select RelacTipActVuln).Count();
            return nRelac;
        }

        //Método que elimina (borrado lógico) un conjunto de relaciones Amenaza - Control de la matriz
        public static void EliminarAmenContr(int IdAmenaza, int IdControl)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Matriz_Amenazas_Controles nuevaRelacion =
                new Matriz_Amenazas_Controles();
            nuevaRelacion.IdAmenaza = IdAmenaza;
            nuevaRelacion.IdControl = IdControl;
            Matriz_Amenazas_Controles RelacionEliminar
                        = (from RelMatriz in agenteBD.Matriz_Amenazas_ControlesEstablecer
                           where RelMatriz.IdAmenaza == nuevaRelacion.IdAmenaza &&
                                 RelMatriz.IdControl == nuevaRelacion.IdControl
                           select RelMatriz).First();
            //Seteamos la Relación a False
            RelacionEliminar.Actual = false;
            agenteBD.SaveChanges();
        }

        //Método que hace un borrado lógico de todas las relaciones dependientes de una lista de Amenazas
        public static List<Matriz_Amenazas_Controles> EliminaRelacionesPorAmenaza(List<Amenazas> LAmenazas)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada amenaza de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<Matriz_Amenazas_Controles> LRelacionesEliminadas = new List<Matriz_Amenazas_Controles>();
            foreach (Amenazas A in LAmenazas)
            {
                //Recogemos las Relaciones actuales de la Matriz
                IQueryable<Matriz_Amenazas_Controles> RelacTipActAmenCrit = from Relac in agenteBD.Matriz_Amenazas_ControlesEstablecer
                                                                            where Relac.IdAmenaza == A.IdAmenaza && Relac.Actual == true
                                                                            select Relac;
                if (RelacTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a false
                    foreach (Matriz_Amenazas_Controles Relacion in RelacTipActAmenCrit)
                    {
                        Relacion.Actual = false;
                        //Añadimos a la lista de Relaciones Eliminadas
                        LRelacionesEliminadas.Add(Relacion);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesEliminadas;
        }

        //Método que restaura las relaciones dependendientes de una lista de Ids de Amenaza
        internal static List<Matriz_Amenazas_Controles> RestauraRelacionesPorAmenaza(List<int> LAmenazas)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada amenaza de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<Matriz_Amenazas_Controles> LRelacionesRestauradas = new List<Matriz_Amenazas_Controles>();
            foreach (int IdAmenaza in LAmenazas)
            {
                //Recogemos las Relaciones actuales de la Matriz
                IQueryable<Matriz_Amenazas_Controles> RelacTipActAmenCrit = from Relac in agenteBD.Matriz_Amenazas_ControlesEstablecer
                                                                            where Relac.IdAmenaza == IdAmenaza
                                                                            select Relac;
                if (RelacTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a True
                    foreach (Matriz_Amenazas_Controles Relacion in RelacTipActAmenCrit)
                    {
                        Relacion.Actual = true;
                        //Añadimos a la lista de Relaciones Eliminadas
                        LRelacionesRestauradas.Add(Relacion);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesRestauradas;
        }

        //Método que restaura el conocimiento asociado a una relacion Amenaza - Control
        public static void RestauraConocimientoPorRelacion(List<Matriz_Amenazas_Controles> LAmenazasControles)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Lista de IdsAmenazas e IdTiposAmenazas asociadas
            List<int> LIdsAmenazas = new List<int>();
            List<int> LIdsTipoAmenazas = new List<int>();
            //Recorremos las relaciones seleccionadas 
            foreach (Matriz_Amenazas_Controles Relacion in LAmenazasControles)
            {
                Matriz_Amenazas_Controles RelacionRestaura = (from MatrizAmenContr in agenteBD.Matriz_Amenazas_ControlesEstablecer
                                                              where MatrizAmenContr.IdAmenaza == Relacion.IdAmenaza &&
                                                                    MatrizAmenContr.IdControl == Relacion.IdControl
                                                              select MatrizAmenContr).Single();
                RelacionRestaura.Actual = true;
                //Recogemos los Ids distintos de Amenazas y Tipos de Amenazas asociadas de las relaciones
                if (!LIdsAmenazas.Contains(Relacion.IdAmenaza))
                    LIdsAmenazas.Add(Relacion.IdAmenaza);
                int IdTipoAmenaza = TiposAmenazasFactory.IdTipoAmenaza(Relacion.IdAmenaza);
                if (!LIdsTipoAmenazas.Contains(IdTipoAmenaza))
                    LIdsTipoAmenazas.Add(IdTipoAmenaza);
            }
            //Restauramos las Amenazas y Tipos de Amenazas recogidas a través de sus Ids
            AmenazasFactory.RestauraAmenazaPorRelaciones(LIdsAmenazas);
            TiposAmenazasFactory.RestauraTipoAmenazaPorRelaciones(LIdsTipoAmenazas);
            agenteBD.SaveChanges();

        }
    }
}
